package com.dyava.commons.codec;

import org.apache.commons.io.IOUtils;

import java.io.*;
import java.util.Enumeration;
import java.util.zip.*;

public class ZipUtils {
	static final int BUFFER = 8192;


	private static void compress(File file, ZipOutputStream zipOut, String baseDir) throws IOException{
	    if (file.isDirectory()) {
	        compressDirectory(file, zipOut, baseDir);
	    } else {
	        compressFile(file, zipOut, baseDir);
	    }
	}

	/** 压缩一个目录 */
	private static void compressDirectory(File dir, ZipOutputStream zipOut, String baseDir) throws IOException{
	    File[] files = dir.listFiles();
	    for (int i = 0; i < files.length; i++) {
	        compress(files[i], zipOut, baseDir + dir.getName() + "/");
	    }
	}

	/** 压缩一个文件 */
	private static void compressFile(File file, ZipOutputStream zipOut, String baseDir)  throws IOException{
	    if (!file.exists()){
	        return;
	    }

	    BufferedInputStream bis = null;
	    try {
	        bis = new BufferedInputStream(new FileInputStream(file));
	        ZipEntry entry = new ZipEntry(baseDir + file.getName());
	        zipOut.putNextEntry(entry);
	        int count;
	        byte data[] = new byte[BUFFER];
	        while ((count = bis.read(data, 0, BUFFER)) != -1) {
	            zipOut.write(data, 0, count);
	        }

	    }finally {
	        if(null != bis){
	            bis.close();
	        }
	    }
	}


	/**
	 * 压缩文件
	 * @param srcPath
	 * @param dstPath
	 * @throws IOException
	 */
	public static void compress(String srcPath , String dstPath) throws IOException{
	    File srcFile = new File(srcPath);
	    File dstFile = new File(dstPath);
	    if (!srcFile.exists()) {
	        throw new FileNotFoundException(srcPath + "不存在！");
	    }

	    FileOutputStream out = null;
	    ZipOutputStream zipOut = null;
	    try {
	        out = new FileOutputStream(dstFile);
	        CheckedOutputStream cos = new CheckedOutputStream(out,new CRC32());
	        zipOut = new ZipOutputStream(cos);
	        String baseDir = "";
	        compress(srcFile, zipOut, baseDir);
	    }
	    finally {
	        if(null != zipOut){
	            zipOut.close();
	            out = null;
	        }

	        if(null != out){
	            out.close();
	        }
	    }
	}
	
	
	/**
	 * 解压文件
	 * @param zipFile
	 * @param dstPath
	 * @throws IOException
	 */
	public static void decompress(String zipFile , String dstPath)throws IOException{
	    File pathFile = new File(dstPath);
	    if(!pathFile.exists()){
	        pathFile.mkdirs();
	    }
	    ZipFile zip = new ZipFile(zipFile);
	    for(Enumeration entries = zip.entries();entries.hasMoreElements();){
	        ZipEntry entry = (ZipEntry)entries.nextElement();
	        String zipEntryName = entry.getName();
	        InputStream in = null;
	        OutputStream out = null;
	        try{
	            in =  zip.getInputStream(entry);
	            String outPath = (dstPath+"/"+zipEntryName).replaceAll("\\*", "/");;
	            //判断路径是否存在,不存在则创建文件路径
	            File file = new File(outPath.substring(0, outPath.lastIndexOf('/')));
	            if(!file.exists()){
	                file.mkdirs();
	            }
	            //判断文件全路径是否为文件夹,如果是上面已经上传,不需要解压
	            if(new File(outPath).isDirectory()){
	                continue;
	            }

	            out = new FileOutputStream(outPath);
	            byte[] buf1 = new byte[1024];
	            int len;
	            while((len=in.read(buf1))>0){
	                out.write(buf1,0,len);
	            }
	        }
	        finally {
	            if(null != in){
	                in.close();
	            }

	            if(null != out){
	                out.close();
	            }
	        }
	    }
	}
	
	public static byte[] compress(byte[] srcArr) throws IOException {
		if (srcArr == null) {
			return null;
		}
		ByteArrayOutputStream bosm = new ByteArrayOutputStream();
		GZIPOutputStream gosm = null;
		try {
			gosm = new GZIPOutputStream(bosm);
			gosm.write(srcArr);
			gosm.close();
		} finally {
			IOUtils.closeQuietly(gosm);
		}
		return bosm.toByteArray();
	}

	/* * 字节数组解压缩后返回字符串 */
	public static byte[] uncompress(byte[] zipArr) throws IOException {
		if (zipArr == null) {
			return null;
		}
		ByteArrayOutputStream bosm = new ByteArrayOutputStream();
		GZIPInputStream gism = null;
		try {
			gism = new GZIPInputStream(new ByteArrayInputStream(zipArr));
			byte[] buffer = new byte[1024];
			int n;
			while ((n = gism.read(buffer)) >= 0) {
				bosm.write(buffer, 0, n);
			}
		} finally {
			IOUtils.closeQuietly(gism);
		}
		return bosm.toByteArray();
	}


//	/**
//	 * 压缩字符串为 byte[] 储存可以使用new sun.misc.BASE64Encoder().encodeBuffer(byte[] b)方法
//	 * 保存为字符串
//	 *
//	 * @param str
//	 *            压缩前的文本
//	 * @return
//	 * @throws IOException 
//	 */
//	public static final byte[] compress(byte[] src) throws IOException {
//		if (src == null)
//			return null;
//
//		byte[] compressed;
//		ByteArrayOutputStream out = null;
//		ZipOutputStream zout = null;
//
//		try {
//			out = new ByteArrayOutputStream();
//			zout = new ZipOutputStream(out);
//			zout.putNextEntry(new ZipEntry("0"));
//			zout.write(src);
//			zout.closeEntry();
//			compressed = out.toByteArray();
//		}finally {
//			if (zout != null) {
//				try {
//					zout.close();
//				} catch (IOException e) {
//				}
//			}
//		}
//
//		return compressed;
//	}
//
//	/**
//	 * 将压缩后的 byte[] 数据解压缩
//	 *
//	 * @param compressed
//	 *            压缩后的 byte[] 数据
//	 * @return 解压后的字符串
//	 * @throws IOException 
//	 */
//	public static final byte[] decompress(byte[] compressed) throws IOException {
//		if (compressed == null)
//			return null;
//
//		ByteArrayOutputStream out = null;
//		ByteArrayInputStream in = null;
//		ZipInputStream zin = null;
//		try {
//			out = new ByteArrayOutputStream();
//			in = new ByteArrayInputStream(compressed);
//			zin = new ZipInputStream(in);
//			byte[] buffer = new byte[1024];
//			int offset = -1;
//			offset = zin.read(buffer);
//			while ((offset = zin.read(buffer)) != -1) {
//				out.write(buffer, 0, offset);
//			}
//		}finally {
//			if (zin != null) {
//				try {
//					zin.close();
//				} catch (IOException e) {
//				}
//			}
//		}
//
//		return out.toByteArray();
//	}
}
